Day23 要做的是將輸入的文字轉為聲音
const MESSAGE = "Hello!";
const [text, setText] = useState(MESSAGE);
const synthRef = useRef(window.speechSynthesis);
const utteranceRef = useRef(new SpeechSynthesisUtterance());
const speak = useCallback(() => {
const synth = synthRef.current;
const utterance = utteranceRef.current;
if (synth.speaking) {
synth.cancel();
return;
}
utterance.text = text;
synth.speak(utterance);
}, [text]);
const stop = useCallback(() => {
synthRef.current.cancel();
}, []);
const updateVoice = useCallback((index: number) => {
const voices = synthRef.current.getVoices();
utteranceRef.current.voice = voices[index];
}, []);
const updateRate = useCallback((rate: number) => {
utteranceRef.current.rate = rate;
}, []);
const updatePitch = useCallback((pitch: number) => {
utteranceRef.current.pitch = pitch;
}, []);
return (
<div className="container mx-auto p-4 max-w-lg">
<h1 className="text-2xl font-bold mb-4">Speech Synthesis</h1>
<textarea
className="w-full p-2 border rounded mb-4"
rows={3}
value={text}
onChange={(e) => setText(e.target.value)}
/>
<div className="mb-4">
<label className="block mb-2">Voice:</label>
<select
className="w-full p-2 border rounded"
onChange={(e) => updateVoice(Number(e.target.value))}
>
{synthRef.current.getVoices().map((voice, index) => (
<option key={index} value={index}>
{voice.name} ({voice.lang})
</option>
))}
</select>
</div>
<div className="mb-4">
<label className="block mb-2">Rate:</label>
<input
type="range"
min="0.5"
max="2"
step="0.1"
defaultValue="1"
onChange={(e) => updateRate(Number(e.target.value))}
className="w-full"
/>
</div>
<div className="mb-4">
<label className="block mb-2">Pitch:</label>
<input
type="range"
min="0.5"
max="2"
step="0.1"
defaultValue="1"
onChange={(e) => updatePitch(Number(e.target.value))}
className="w-full"
/>
</div>
<div className="flex justify-between">
<button
type="button"
onClick={speak}
className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600"
>
{synthRef.current.speaking ? "Pause" : "Speak"}
</button>
<button
type="button"
onClick={stop}
className="bg-red-500 text-white px-4 py-2 rounded hover:bg-red-600"
>
Stop
</button>
</div>
</div>
);